import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.stream.Stream;

public class Migration {
    public static void main(String[] args) throws IOException {
        System.out.println("请输入项目根路径");
        Scanner scanner = new Scanner(System.in);
//        String basePath = scanner.nextLine();
        String basePath = "/Users/yangbing/IdeaProjects/cls-ms";
        List<Path> files = new ArrayList<>();
//        files.add(Path.of("/Users/yangbing/IdeaProjects/cls-ms/cls-ms-service-api/cls-ms-third-party-api/src/main/java/com/sinfusi/cls/third/standard/entity/CollectGrantNoticeEntity.java"));
//        files.add(Path.of("/Users/yangbing/IdeaProjects/cls-ms/cls-ms-service-api/cls-ms-post-term-api/src/main/java/com/sinfusi/cls/finance/entity/FmGuaranteeApply.java"));
        searchFiles(Path.of(basePath), files);
        // 处理为 .work 文件
        for (Path file : files) {
            dealFile(file);
        }

        // 将 .work文件处理为 java文件
        for (Path file : files) {
            // 移动策略 覆盖目标文件
            Files.move(Path.of(file + ".work"), file, StandardCopyOption.REPLACE_EXISTING);
        }
    }

    private static void searchFiles(Path basePath, List<Path> filePaths) {
        if (!Files.exists(basePath)) {
            throw new RuntimeException("目录不存在[" + basePath + "]");
        }
        try (Stream<Path> list = Files.list(basePath)) {
            list.forEach(path -> {
                if (Files.isDirectory(path)) {
                    searchFiles(path, filePaths);
                } else {
                    Path fileName = path.getFileName();
                    if (fileName.toString().endsWith("java")) {
                        filePaths.add(path);
                    }
                }
            });
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static String specialine = "123123123123123123123123123123123";

    private static boolean dealFile(Path filePath) {
        try (BufferedReader br = Files.newBufferedReader(filePath); BufferedWriter bw = Files.newBufferedWriter(Path.of(filePath + ".work"))) {
            AtomicBoolean hasImportSchema = new AtomicBoolean(false);
            br.lines().map(line -> {
                /*
                    @ApiSupport(order = 20)
                    @ApiOperationSupport(order = 1)
                    @Api(tags = "业务资料清单管理")
                    @ApiOperation(value = "W-I 生成资料清单", httpMethod = "POST")
                    @ApiModel("生成资料清单RO")
                    @ApiModelProperty("是否保存到数库")
                 */

                // 执行处理
                // 移除 knife4j注解 begin
                if (line.contains("com.github.xiaoymin.knife4j.annotations")) {
                    return specialine;
                }
                if (line.contains("@ApiSupport") || line.contains("@ApiOperationSupport(")) {
                    return specialine;
                }
                // 移除 knife4j注解 end

                if (line.matches("[ \t]*import[ ]*io.swagger.annotations.Api[ ]*;")) {
                    return line.replace("io.swagger.annotations.Api", "io.swagger.v3.oas.annotations.tags.Tag");
                }

                if (line.matches("[ \t]*import[ ]*io.swagger.annotations.ApiOperation[ ]*;")) {
                    return line.replace("io.swagger.annotations.ApiOperation", "io.swagger.v3.oas.annotations.Operation");
                }

                if (line.matches("[ \t]*import[ ]*io.swagger.annotations.ApiModelProperty[ ]*;")) {
                    if (hasImportSchema.get()) {
                        return specialine;
                    }
                    hasImportSchema.set(true);
                    return line.replace("io.swagger.annotations.ApiModelProperty", "io.swagger.v3.oas.annotations.media.Schema");
                }

                if (line.matches("[ \t]*import[ ]*io.swagger.annotations.ApiModel[ ]*;")) {
                    if (hasImportSchema.get()) {
                        return specialine;
                    }
                    hasImportSchema.set(true);
                    return line.replace("io.swagger.annotations.ApiModel", "io.swagger.v3.oas.annotations.media.Schema");
                }


                if (line.matches("[ \t]*@Api[ ]*[(]{1}[\\S \\t]*")) {
                    Map<String, String> props = findProps(line);
                    System.out.println("(tags)Api:\t" + props);
                    Convert.validProps(filePath, "Api", props, "tags");
                    return "@Tag(name = \"" + props.getOrDefault("tags", "") + "\")";
                }
                if (line.matches("[ \t]*@ApiOperation[ ]*[(]{1}[\\S \\t)]*")) {
                    Map<String, String> props = new LinkedHashMap<>();
                    if (line.matches("[ \t]*@ApiOperation[ ]*[(]{1}[ ]*\"[\\S \\t]*\"[ ]*[)]{1}[ ]*")) {
                        String value = findSingleValue(line);
                        props.put("value", value);
                    } else {
                        props.putAll(findProps(line));
                    }
                    return Convert.convertApiOperation(line,filePath, props);
                }
                if (line.matches("[ \t]*@ApiModel[ ]*[(]{1}[\\S \\t]*")) {
                    Map<String, String> props = new LinkedHashMap<>();
                    if (line.matches("[ \t]*@ApiModel[ ]*[(]{1}[ ]*\"[\\S \\t]*\"[ ]*[)]{1}[ ]*")) {
                        String value = findSingleValue(line);
                        props.put("value", value);
                    } else {
                        props.putAll(findProps(line));
                    }
                    return Convert.convertApiModel(filePath, props);
                }
                if (line.matches("[ \t]*@ApiModelProperty[ ]*[(]{1}[\\S \\t]*")) {
                    Map<String, String> props = new LinkedHashMap<>();
                    if (line.matches("[ \t]*@ApiModelProperty[ ]*[(]{1}[ ]*\"[\\S \\t]*\"[ ]*[)]{1}[ ]*")) {
                        String value = findSingleValue(line);
                        props.put("value", value);
                    } else {
                        props.putAll(findProps(line));
                    }
                    return Convert.convertApiModelProperty(line,filePath, props);
                }
                return line;
            }).filter(line -> !specialine.equals(line)).forEach(str -> {
                try {
                    bw.write(str);
                    bw.write("\n");
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return false;
    }

    private static Map<String, String> findProps(String newLine) {
        // 换个方式
//        Matcher matcher = Patterns.PATTERN_PROPS.matcher(line);
//        while (matcher.find()) {
//            String str = matcher.group();
//            String[] split = str.split("=");
//            String key = split[0].trim();
//            String value = split[1].trim();
//            if (value.startsWith("\"")) {
//                value = value.substring(1);
//            }
//            if (value.endsWith("\"")) {
//                value = value.substring(0, value.length() - 1);
//            }
//            data.put(key, value);
//        }
        /*
        截取
         */
        String line = newLine;
        line = line.substring(line.indexOf("(") + 1);
        Map<String, String> data = new LinkedHashMap<>();
        while (line.contains("=")) {
            String key = line.substring(0, line.indexOf("="));
            key = key.replace(",", "").trim();
            line = line.substring(line.indexOf("=") + 1).trim();
            int endIndex = 0;
            String value;
            if (line.startsWith("\"")) {
                endIndex = findCharIndex(2, '"', line);
                value = line.substring(1, endIndex);
            } else if(line.contains(",")) {
                endIndex = findCharIndex(1, ',', line);
                value = line.substring(0, endIndex);
                value = value.trim();
            }else{
                endIndex = findCharIndex(1, ')', line);
                value = line.substring(0, endIndex);
                value = value.trim();
            }
            line = line.substring(endIndex + 1);
            data.put(key, value);
        }
        System.out.println("line\t" + newLine);
        System.out.println("data\t" + data);
        return data;
    }

    private static String findSingleValue(String line) {
        return line.split("\"")[1];
    }

    private static int findCharIndex(int i, char c, String line) {
        int count = 0;
        char[] chars = line.toCharArray();
        for (int i1 = 0; i1 < chars.length; i1++) {
            if (i1==0?chars[i1] == c:chars[i1] == c&&chars[i1-1] != '\\' ) {
                count++;
                if (count == i) {
                    return i1;
                }
            }
        }
        return -1;
    }

//    public static void main(String[] args) {
//        String line = "@ApiOperation(value = \"通过订单号修改车辆数据\", notes = \"放款申请保存时修改车辆数据car_perfect_status_id =11283001 or 11283003,can_edit_id=11190002,car_dep_state_id=11071000\")";
//        System.out.println(findProps(line));
//    }
}
